package com.chenyun.store.aws;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.chenyun.common.constants.SysConstants;
import com.chenyun.common.enums.StoreTypeEnum;
import com.chenyun.common.exceptions.BusinessException;
import com.chenyun.satoken.starter.util.SaUtil;
import com.chenyun.store.pojo.StoreDTO;
import org.springframework.lang.Nullable;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 上传文件工厂
 * 支持多租户
 *
 * @author: Lonni
 * @date: 2023/11/6 0006 10:42
 */
public class OssFactory implements Serializable {


    /**
     * 存储租户文件存储服务类
     * key:租户id
     * key:文件存储类型 只包含本地和云存储,如果配置了多个云存储,则使用最后一个
     * value:service  具体业务实现类
     */
    private static final Map<String, Map<String, IOssClientService>> OSS_CLIENT_CACHE = new ConcurrentHashMap();

    /**
     * 标识云存储的key
     */
    private static final String  YUN_OSS_TYPE="oss-yun";

    /**
     * 初始化文件存储
     *
     * @param storeSetting 文件存储配置 json数组
     * @param tid          租户id
     */
    public static void init(String storeSetting, @Nullable String tid) {
        List<StoreDTO> storeDTOS = null;
        try {
            storeDTOS = JSON.parseArray(storeSetting, StoreDTO.class);
        } catch (Exception exception) {
            throw new BusinessException("解析文件存储配置失败");
        }
        List<StoreDTO> dtos = storeDTOS.stream().filter(p -> p.getEnable()).collect(Collectors.toList());
       if (CollectionUtil.isEmpty(dtos)){
           return;
       }
        if (dtos.size() > 1) {
            throw new BusinessException("只能开启一个上传配置");
        }
        tid = StrUtil.isBlank(tid) ? SysConstants.DEFAULT_TENANT_ID.toString() : tid;
        IOssClientService service = null;
        Map<String, IOssClientService> ossClientServiceMap = OSS_CLIENT_CACHE.get(tid);
        if (CollectionUtil.isEmpty(ossClientServiceMap)){
            OSS_CLIENT_CACHE.put(tid,new HashMap<>());
            ossClientServiceMap = OSS_CLIENT_CACHE.get(tid);
        }
        if (dtos.get(0).getTypeEnum() == StoreTypeEnum.LOCAL) {
            service = new OssLocalClientService(dtos.get(0));
            ossClientServiceMap.put(StoreTypeEnum.LOCAL.getCode(),service);
        } else {
            service = new Aws3ClientService(dtos.get(0));
            ossClientServiceMap.put(YUN_OSS_TYPE,service);
        }
        OSS_CLIENT_CACHE.put(tid,ossClientServiceMap);

    }


    /**
     * 获取文件上传存储
     *
     * @return
     */
    public static IOssClientService getOssClient() {
        String clientId = SaUtil.getLoginUser().getClientId();
        return getOssClient(clientId);
    }

    public static IOssClientService getOssClientLocal(){
        String clientId = SaUtil.getLoginUser().getClientId();
        Map<String, IOssClientService> ossClientServiceMap = OSS_CLIENT_CACHE.get(clientId);
        if (CollectionUtil.isEmpty(ossClientServiceMap) ) {
            throw new BusinessException("文件客户端未初始化!");
        }
        return ossClientServiceMap.getOrDefault(StoreTypeEnum.LOCAL.getCode(),null);

    }


    /**
     * 获取指定应用下的oss  优先拿云存储,没有云存储则拿本地
     * 为空标识获取默认租户的配置
     *
     * @param tenantId 租户ID
     * @return
     */
    static IOssClientService getOssClient(String tenantId) {
        Map<String, IOssClientService> ossClientServiceMap = OSS_CLIENT_CACHE.get(tenantId);
        if (CollectionUtil.isEmpty(ossClientServiceMap) ) {
            throw new BusinessException("文件客户端未初始化!");
        }
        IOssClientService iOssClientService = ossClientServiceMap.getOrDefault(YUN_OSS_TYPE,null);
        if (iOssClientService==null){
            iOssClientService= ossClientServiceMap.getOrDefault(StoreTypeEnum.LOCAL.getCode(),null);
        }
        if (iOssClientService==null ) {
            throw new BusinessException("文件客户端未初始化!");
        }

        return iOssClientService;

    }


}



